﻿using System.Linq.Expressions;
using RpcModel;
using SqlSugar;

namespace SqlSugarHelper
{
    public interface IRepository<T> where T : class, new()
    {
        bool UpdateOnly(T[] datas, Expression<Func<T, object>> setCol);
        Result[] Gets<Table, Result>(ISugarQueryable<Table>[] list, string selector, string orderBy) where Table : class, new();
        Result Get<Table, Result>(ISugarQueryable<Table>[] list, string selector, string orderBy) where Table : class, new();
        Result[] Gets<Table, Result>(ISugarQueryable<Table>[] list, string selector) where Table : class, new();
        SqlSugarProvider Provider { get; }
        ISugarQueryable<T> Queryable { get; }
        ISqlQueue<T> BeginQueue();
        Result Get<Result>(ISugarQueryable<Result>[] list, string orderBy) where Result : class, new();
        Result[] Gets<Result>(ISugarQueryable<Result>[] list, string orderBy) where Result : class, new();
        Result[] Gets<Result>(ISugarQueryable<Result>[] list) where Result : class, new();
        Result[] Gets<Table, Result>(ISugarQueryable<Table>[] list, Expression<Func<Table, Result>> selector, string orderBy) where Table : class, new();

        Result[] Gets<Table, Result>(ISugarQueryable<Table>[] list, Expression<Func<Table, Result>> selector) where Table : class, new();
        Result Get<Table, Result>(ISugarQueryable<Table>[] list, Expression<Func<Table, Result>> selector, string orderBy) where Table : class, new();
        Result Avg<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector);

        Result Max<Result>(Expression<Func<T, Result>> selector);
        Result Min<Result>(Expression<Func<T, Result>> selector);

        Result Avg<Result>(Expression<Func<T, Result>> selector);

        int Count();
        int Count(Expression<Func<T, bool>> filter);
       
      
        bool Delete(Expression<Func<T, bool>> filter);
        IDeleteable<T> Delete();
        bool Delete<Other>(Expression<Func<T, Other, bool>> filter) where Other : class, new();
        int ExecuteSql(string sql, params SugarParameter[] param);
        T Get(Expression<Func<T, bool>> filter);
        T Get(Expression<Func<T, bool>> filter, string orderby);
        T Get(string sql, params SugarParameter[] param);
        Result Get<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector);
        Result Get<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector, string orderby);
        T[] GetAll();
        T[] GetAll(string orderby);
        Result[] GetAll<Result>(Expression<Func<T, Result>> selector);
        Result[] GetAll<Result>(Expression<Func<T, Result>> selector, string orderby);
        T[] Gets(Expression<Func<T, bool>> filter);
        T[] Gets(Expression<Func<T, bool>> filter, string orderby);
        Result[] Gets<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector);
        Result[] Gets<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector, string orderby);
        Result[] Gets<Result>(string sql, params SugarParameter[] param) where Result : class, new();
        Result[] GroupBy<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, object>> group, Expression<Func<T, bool>> having, Expression<Func<T, Result>> selector);
        Result[] GroupBy<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, object>> group, Expression<Func<T, Result>> selector);

        Result[] GroupBy<Result>(Expression<Func<T, object>> group, Expression<Func<T, Result>> selector);
        void Insert(T item);

        long InsertReutrnIdentity(T item);
        void Insert(T[] items);
        int Insert(List<T> datas, Expression<Func<T, object>> filter);
        bool IsExist<TResult>(Expression<Func<T, bool>> filter, Expression<Func<T, TResult>> selector);
        Result[] Join<TInner, Result>(Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, bool>> filter, Expression<Func<T, TInner, Result>> selector) where TInner : class;
        Result[] JoinGroupBy<TInner, TKey, TResult, Result, GroupKey>(Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, bool>> filter, Expression<Func<T, TInner, object>> group, Expression<Func<T, TInner, Result>> selector) where TInner : class;
        Result[] JoinQuery<TInner, Result>(Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, bool>> filter, Expression<Func<T, TInner, Result>> selector, IBasicPage pager, out long count) where TInner : class;
        Result[] JoinQuery<TInner, Result>(Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, bool>> filter, Expression<Func<T, TInner, Result>> selector, int index, int size, Expression<Func<T, TInner, object>> orderby, OrderByType byType, out long count) where TInner : class;
        Result Max<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector);
        Result Min<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector);
        T[] Query(Expression<Func<T, bool>> filter, IBasicPage pager, out int count);
        T[] Query(IBasicPage pager, out long count);
        Result[] Query<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector, IBasicPage pager, out long count);
        Result Sum<Result>(Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector);
        bool Update(T data, string[] whereColumn);
        bool Update(T data, string[] whereColumn, Expression<Func<T, bool>> filter);
        bool Update(T[] datas, params string[] ignoreColumn);
        IUpdateable<T> Update();
        bool Update(Expression<Func<T, T>> columns);
        bool Update<Set>(Set set, Expression<Func<T, bool>> filter);
        bool Update<Set>(Set set, Expression<Func<T, object>> filter);
        bool Update(T[] datas, Expression<Func<T, object>> filter);
        bool Update(Expression<Func<T, T>> columns, Expression<Func<T, bool>> filter);
        int UpdateByRowIndex(Expression<Func<T, T>> columns, Expression<Func<T, bool>> filter);
        bool Update(Expression<Func<T, T>> columns, string[] whereColumn);
        bool Update(Expression<Func<T, bool>> columns, Expression<Func<T, bool>> filter);
        bool Update(Expression<Func<T, T>> columns, Expression<Func<T, object>> filter);

        bool Update(T source, T set);
        bool Update<Set>(T source, Set set);

        bool AddOrUpdate(List<T> datas);
        IStorageable<T> Storageable(List<T> datas);
        bool AddOrUpdate(List<T> datas, Expression<Func<T, object>> filter);
        bool AddOrUpdate(List<T> datas, Func<StorageableInfo<T>, bool> insert, Func<StorageableInfo<T>, bool> update);

        bool AddOrUpdate(List<T> datas, Expression<Func<T, object>> filter, Expression<Func<T, object>> update);
      
    }
}